\section{Introduction}
\label{sec-introduction}

Good debugging tools are essential for the productivity of software
developers.  In this paper, we are concerned with \emph{application
  programmers} as opposed to \emph{system programmers}.  The
difference, in the context of this paper, is that the techniques that
we suggest are not adapted to debugging the system itself, such as the
compiler.  Instead, throughout this paper, we assume that, as far as
the application programmer is concerned, the semantics of the code
generated by the compiler corresponds to that of the source code.

In this paper, we are mainly concerned with \commonlisp{}
\cite{ansi:common:lisp} implementations distributed as so-called
FLOSS, i.e., ``Free, Libre, and Open Source Software''.  While some
such implementations are excellent in terms of the quality of the code
that the compiler generates, most leave much to be desired when it
comes to debugging tools available to the application programmer.

Perhaps the most advanced development environment available to
application programmers using FLOSS \commonlisp{} implementations is
the one that consists of GNU Emacs%
\footnote{https://www.gnu.org/software/emacs/manual/emacs.html}
(also \cite{10.5555:2167272} \cite{Stallman:emacs})
with SLIME%
\footnote{https://common-lisp.net/project/slime/doc/html/}.
Many application
programmers consider this development environment to be outstanding.
Some even believe that it is one of the best, no matter the
programming language under consideration.

However, although this environment does a fairly good job with
exploiting the features of the \commonlisp{} implementations that it
supports, limitations of those implementations severely restrict what
the application programmer can do.  In particular, most of these
implementations have only very limited facilities for setting
breakpoints (unconditional or conditional) and for stepping.

Even in implementations that allow the programmer to set a breakpoint
in some code, the places where it is allowed are necessarily
restricted, given how breakpoints are typically implemented.  The
reason for this restriction is that such a breakpoint would be visible
to all callers of the code in which the breakpoint is set.  When these
callers include important system code such as the compiler, or perhaps
the debugger itself, setting such a breakpoint would make the entire
system useless.  This restriction typically applies also to tracing.
Most \commonlisp{} implementations would either not allow for the
programmer to trace important system functions such as
\texttt{make-instance} or \texttt{shared-initialize}, or these
functions would be rendered useless with any such attempt.  The reason
is of course that these functions would be called by the system
itself, so that output would be drowned in traces of calls that are
unimportant to the application programmer.

In this paper, we suggest a technique that solves these problems.  The
key features of this technique is that breakpoints and traces take
effect only in a thread that is executed from a special \emph{debugger
  thread}.  Thus, even though a function might contain a breakpoint,
when that function is called as a normal part of an application, the
breakpoint will not have any effect.  Only when that function is
called (directly or indirectly) from the special debugger thread is
the breakpoint visible.

The technique presented in this paper is yet to be implemented.  We
have, however, conducted experiments that suggest that it is entirely
viable.  We plan to make it the default technique used in our system
\sicl{} (see \refSec{sec-sicl-features}), currently under development.

Throughout this paper, we use the term \emph{user} to mean the person
operating the debugger or some debugging-related facility, so as to
distinguish this person from the \emph{application programmer}, by
which we mean the author of the code being debugged.  The two can
obviously be one and the same person in two different roles.
